
package org.jivesoftware.util;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
* <p>Title: ETopGlobals</p>
* <p>Description: 全局配置类 </p>
* <p>Company:lgliushq@163.com </p>
* @author    Liusq
* @date       2014-5-8
 */
public class CGlobals {

	private static final Logger Log = LoggerFactory.getLogger(CGlobals.class);

	/**
	 * 配置文件
	 */
    private static String CONFIG_FILENAME = "conf" + File.separator + "server.xml";
    
    /**
     * 数据库sql配置文件
     */
    private static String SQL_FILENAME = "conf" + File.separator + "sql.xml";
   
    /**
     * Location of the jiveHome directory. All configuration files should be
     * located here.
     */
    private static String home = null;

    public static boolean failedLoading = false;

    private static XMLProperties xmlProperties = null;
    
    private static XMLProperties sqlProperties = null;

    private static Locale locale = null;
    private static TimeZone timeZone = null;
    private static DateFormat dateFormat = null;
    private static DateFormat dateTimeFormat = null;
    private static DateFormat timeFormat = null;
    
    private static Document doc = null;

    /**
     * 获取位置
     * @return
     */
    public static Locale getLocale() {
        if (locale == null) {
            if (xmlProperties != null) {
                String [] localeArray;
                String localeProperty = xmlProperties.getProperty("locale");
                if (localeProperty != null) {
                    localeArray = localeProperty.split("_");
                }
                else {
                    localeArray = new String[] {"", ""};
                }

                String language = localeArray[0];
                if (language == null) {
                    language = "";
                }
                String country = "";
                if (localeArray.length == 2) {
                    country = localeArray[1];
                }
                // If no locale info is specified, return the system default Locale.
                if (language.equals("") && country.equals("")) {
                    locale = Locale.getDefault();
                }
                else {
                    locale = new Locale(language, country);
                }
            }
            else {
                return Locale.getDefault();
            }
        }
        return locale;
    }

    /**
     * 设置区域
     * @param newLocale
     */
    public static void setLocale(Locale newLocale) {
        locale = newLocale;
        // Save values to Jive properties.
        setXMLProperty("locale", locale.toString());

        // Reset the date formatter objects
        timeFormat = null;
        dateFormat = null;
        dateTimeFormat = null;
    }

    public static TimeZone getTimeZone() {
        if (timeZone == null) {
            return TimeZone.getDefault();
        }
        return timeZone;
    }

    public static void setTimeZone(TimeZone newTimeZone) {
        timeZone = newTimeZone;
        if (timeFormat != null) {
            timeFormat.setTimeZone(timeZone);
        }
        if (dateFormat != null) {
            dateFormat.setTimeZone(timeZone);
        }
        if (dateTimeFormat != null) {
            dateTimeFormat.setTimeZone(timeZone);
        }
    }

    /**
     * 格式化时间
     * @param date
     * @return
     */
    public static String formatTime(Date date) {
        if (timeFormat == null) {
            DateFormat instance = DateFormat.getTimeInstance(DateFormat.SHORT, getLocale());
            instance.setTimeZone(getTimeZone());
            return instance.format(date);
        }
        return timeFormat.format(date);
    }

    /**
     * 格式化日期
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        if (dateFormat == null) {
            DateFormat instance = DateFormat.getDateInstance(DateFormat.MEDIUM, getLocale());
            instance.setTimeZone(getTimeZone());
            return instance.format(date);
        }
        return dateFormat.format(date);
    }

    /**
     * 格式化日期时间
     * @param date
     * @return
     */
    public static String formatDateTime(Date date) {
        if (dateTimeFormat == null) {
            DateFormat instance = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
                    DateFormat.MEDIUM, getLocale());
            instance.setTimeZone(getTimeZone());
            return instance.format(date);
        }
        return dateTimeFormat.format(date);
    }

    public static String getHomeDirectory() {
        if (xmlProperties == null) {
            loadSetupProperties();
        }
        return home;
    }

    /**
     * 获取根路径
     * @param date
     * @return
     */
    public static void setHomeDirectory(String pathname) {
        File mh = new File(pathname);
        // Do a permission check on the new home directory
        if (!mh.exists()) {
            Log.error("Error - the specified home directory does not exist (" + pathname + ")");
        }
        else if (!mh.canRead() || !mh.canWrite()) {
                Log.error("Error - the user running this application can not read " +
                        "and write to the specified home directory (" + pathname + "). " +
                        "Please grant the executing user read and write permissions.");
        }
        else {
        	System.setProperty("etopHome",pathname);
            home = pathname;
        }
    }

    /**
     * 获取配置文件属性
     * @param name
     * @return
     */
    public static String getXMLProperty(String name) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }

        // home not loaded?
        if (xmlProperties == null) {
            return null;
        }

        return xmlProperties.getProperty(name);
    }
    
    /**
     * 获取sql语句
     * @param name
     * @return
     */
    @Deprecated
    public static String getSQLProperty(String name) {
    	if (sqlProperties == null) {
    		loadSQLProperties();
    	}
    	
    	// home not loaded?
    	if (sqlProperties == null) {
    		return null;
    	}
    	
    	return sqlProperties.getProperty(name);
    }

    /**
     * 获取配置文件属性
     * @param name
     * @return
     */
    public static String getXMLProperty(String name, String defaultValue) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }

        // home not loaded?
        if (xmlProperties == null) {
            return null;
        }

        String value = xmlProperties.getProperty(name);
        if (value == null) {
            value = defaultValue;
        }
        return value;
    }
    
    /**
     * 获取配置文件属性
     * @param name
     * @return int
     */
    public static int getXMLProperty(String name, int defaultValue) {
        String value = getXMLProperty(name);
        if (value != null) {
            try {
                return Integer.parseInt(value);
            }
            catch (NumberFormatException nfe) {
                // Ignore.
            }
        }
        return defaultValue;
    }
    /**
     * 获取配置文件属性
     * @param name
     * @return boolean
     */
    public static boolean getXMLProperty(String name, boolean defaultValue) {
        String value = getXMLProperty(name);
        if (value != null) {
            return Boolean.valueOf(value);
        }
        return defaultValue;
    }

    /**
     * 设置属性
     * @param name
     * @param value
     */
    public static void setXMLProperty(String name, String value) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }

        // jiveHome not loaded?
        if (xmlProperties != null) {
            xmlProperties.setProperty(name, value);
        }
    }

    /**
     * 设置属性
     * @param name
     * @param value
     */
    public static void setXMLProperties(Map<String, String> propertyMap) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }

        if (xmlProperties != null) {
            xmlProperties.setProperties(propertyMap);
        }
    }

    public static List getXMLProperties(String parent) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }

        // jiveHome not loaded?
        if (xmlProperties == null) {
            return Collections.EMPTY_LIST;
        }

        String[] propNames = xmlProperties.getChildrenProperties(parent);
        List<String> values = new ArrayList<String>();
        for (String propName : propNames) {
            String value = getXMLProperty(parent + "." + propName);
            if (value != null) {
                values.add(value);
            }
        }

        return values;
    }

    
    /**
     * 删除设置属性
     * @param name
     * @param value
     */
    public static void deleteXMLProperty(String name) {
        if (xmlProperties == null) {
            loadSetupProperties();
        }
        xmlProperties.deleteProperty(name);
    }

    public static void setConfigName(String configName) {
        CONFIG_FILENAME = configName;
    }

    static String getConfigName() {
        return CONFIG_FILENAME;
    }
    
    static String getB2CConfigName(String name) {
        return name;
    }

    /**
     * 载入资源我文件
     */
    private synchronized static void loadSetupProperties() {
        if (xmlProperties == null) {
            // If home is null then log that the application will not work correctly
            if (home == null && !failedLoading) {
                failedLoading = true;
                StringBuilder msg = new StringBuilder();
                msg.append("Critical Error! The home directory has not been configured, \n");
                msg.append("which will prevent the application from working correctly.\n\n");
                System.err.println(msg.toString());
            }
            // Create a manager with the full path to the xml config file.
            else {
                try {
                    xmlProperties = new XMLProperties(home + File.separator + getConfigName());
                }
                catch (IOException ioe) {
                    Log.error(ioe.getMessage(), ioe);
                    failedLoading = true;
                }
            }
        }
    }
    
    /**
     * 载入sql配置文件
     */
	private synchronized static void loadSQLProperties() {
		if (sqlProperties == null) {
			// If home is null then log that the application will not work
			// correctly
			// Create a manager with the full path to the xml config file.
			try {
				sqlProperties = new XMLProperties(home + File.separator
						+ SQL_FILENAME);
			} catch (IOException ioe) {
				Log.error(ioe.getMessage(), ioe);
			}
		}
	}
}